package ac.github.oa.api.compat

import ac.github.oa.api.OriginAttributeAPI
import ac.github.oa.api.event.entity.ProxyDamageEvent
import ac.github.oa.internal.base.enums.PriorityEnum
import ac.github.oa.internal.base.event.impl.isMagic
import ac.github.oa.internal.base.event.impl.isPhysics
import ac.github.oa.internal.core.attribute.impl.Damage
import io.lumine.xikage.mythicmobs.adapters.AbstractEntity
import io.lumine.xikage.mythicmobs.io.MythicLineConfig
import io.lumine.xikage.mythicmobs.logging.MythicLogger
import io.lumine.xikage.mythicmobs.skills.ITargetedEntitySkill
import io.lumine.xikage.mythicmobs.skills.SkillMetadata
import io.lumine.xikage.mythicmobs.skills.damage.DamagingMechanic
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.entity.EntityDamageEvent
import taboolib.common.platform.function.info
import taboolib.library.reflex.Reflex.Companion.getProperty
import taboolib.library.reflex.Reflex.Companion.setProperty
import taboolib.module.nms.MinecraftVersion

class MythicMobAttack(line: String, mlc: MythicLineConfig) :  DamagingMechanic(line, mlc), ITargetedEntitySkill {

    val cause = mlc.getPlaceholderString("cause","physics")
    val vigor = mlc.getPlaceholderDouble("vigor","1.0")
    val amount = mlc.getPlaceholderDouble("amount","0")

    val AbstractEntity.bukkitLivingEntity: LivingEntity
        get() = this.bukkitEntity as LivingEntity

    override fun castAtEntity(data: SkillMetadata, target: AbstractEntity): Boolean {
        return if (!target.isDead && !data.caster.isUsingDamageSkill && (!target.isLiving || target.health > 0.0)) {
            val damage = amount[data, target] * data.power.toDouble()
            doDamage(target.bukkitLivingEntity, cause.get(),vigor.get(),damage,data.caster.entity.bukkitLivingEntity)
            true
        } else {
            false
        }
    }

    fun doDamage(entity: LivingEntity,cause: String, vigor: Double,damage: Double, source: LivingEntity) {

        val event = ProxyDamageEvent(EntityDamageByEntityEvent(source, entity, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 0.0))
        event.customCause = cause
        val context = event.createDamageContext()
        // 兼容力度
        context.vigor = vigor

        if (context.isPhysics) {
            context.addDamage(Damage.physical,damage)
        } else if (context.isMagic) {
            context.addDamage(Damage.magic,damage)
        }

        if (ac.github.oa.api.event.entity.EntityDamageEvent(context, PriorityEnum.PRE).call()) {
            OriginAttributeAPI.callDamage(context)
            if (ac.github.oa.api.event.entity.EntityDamageEvent(context, PriorityEnum.POST).call()) {
                entity.lastDamageCause = event.origin
                doDamage(source, entity, context.totalDamage.coerceAtLeast(0.0))
            }
        }

    }


    fun doDamage(source: LivingEntity?, entity: LivingEntity, damage: Double) {
        entity.noDamageTicks = 0
        // 如果实体血量 - 预计伤害值 < 0 提前设置击杀者
        if (source != null && entity.health - damage <= 0 && source is Player) {
            entity.setKiller(source)
        }
        entity.damage(damage)
    }

    fun LivingEntity.setKiller(source: LivingEntity) {
        when (MinecraftVersion.major) {
            // 1.12.* 1.16.*
            4, 8 -> setProperty("entity/killer", source.getProperty("entity"))
            // 1.15.* 1.17.* bc
            7, 9 -> setProperty("entity/bc", source.getProperty("entity"))
            // 1.18.2 bc 1.18.1 bd
            10 -> if (MinecraftVersion.minecraftVersion == "v1_18_R2") {
                setProperty("entity/bc", source.getProperty("entity"))
            } else {
                setProperty("entity/bd", source.getProperty("entity"))
            }
            // 1.18.* 1.19.* bd
            11 -> setProperty("entity/bd", source.getProperty("entity"))

        }
    }

}